﻿using Cysharp.Threading.Tasks;
using DG.Tweening;
using System.Collections.Generic;
using UnityEngine;

namespace Client.Hotfix
{
    /// <summary>
    /// 消息Toast系统
    /// </summary>
    [UGFM(UGFMWeight.MessageToastSystem)]
    public class MessageToastSystem : IAwake, IUpdate, IDestroy
    {
        private UIToast uiToast;
        private float messageDuration = 2f;
        private float fadeDuration = 0.5f;
        private float messageSpacing = 10f;
        private float scrollSpeed = 200f;

        private int initialPoolSize = 5;
        private int maxPoolSize = 20;

        private int showMarqueeTime = 10;

        private Vector2 initialPosition = new Vector2(0, 200f); // 默认位置

        private Queue<string> messageQueue = new Queue<string>();
        private List<MessageToast> activeMessages = new List<MessageToast>();
        private Queue<MessageToast> messagePool = new Queue<MessageToast>();
        private Queue<string> messsageMarquee = new Queue<string>();
        private bool isProcessingQueue = false;
        private bool isScrolling = false;

        private bool isProcessingMarquess = false;

        private bool enabale = false;
        public async void Awake()
        {
            this.Log("[System] MessageToastSystem is running...");
            if (enabale)
            {
                uiToast = await UGF.Instance.Resolve<UIService>().Show<UIToast>();
                InitializePool();
            }
        }
        public void Update()
        {
            // 如果有消息在滚动，更新所有消息位置
            if (isScrolling)
            {
                UpdateMessagePositions();
            }

            if (messsageMarquee.Count > 0)
            {
                if (!isProcessingMarquess)
                {
                    PlayMarquessTween();
                    isProcessingMarquess = true;
                }
            }
        }

        public void Destroy()
        {
            ClearPool();
            UGF.Instance.Resolve<UIService>().Destroy<UIToast>();
        }

        public void ShowMessage(string content)
        {
            messageQueue.Enqueue(content);

            if (!isProcessingQueue)
            {
                ProcessMessageQueue();
            }
        }

        #region Toast

        // 初始化对象池
        private void InitializePool()
        {
            for (int i = 0; i < initialPoolSize; i++)
            {
                CreateNewPoolItem();
            }
        }
        // 创建新的池对象
        private void CreateNewPoolItem()
        {
            if (messagePool.Count >= maxPoolSize) return;

            GameObject messageObj = GameObject.Instantiate(uiToast.messageItem, uiToast.UIGameObject.transform);
            MessageToast messageToast = new MessageToast();
            messageToast.InitializePoolItem(messageObj);
            // 初始状态设为隐藏
            messageObj.SetActive(true);
            messagePool.Enqueue(messageToast);
        }

        // 从对象池获取消息
        private MessageToast GetMessageFromPool()
        {
            if (messagePool.Count == 0)
            {
                // 如果池为空，创建新对象
                CreateNewPoolItem();

                if (messagePool.Count == 0)
                {
                    Debug.LogWarning("对象池已满，无法创建新消息");
                    return null;
                }
            }

            MessageToast messageTip = messagePool.Dequeue();
            messageTip.entity.SetActive(true);
            return messageTip;
        }


        // 将消息返回对象池
        private void ReturnMessageToPool(MessageToast messageTip)
        {
            if (messagePool.Count >= maxPoolSize)
            {
                // 如果池已满，直接销毁
                GameObject.Destroy(messageTip.entity);
                return;
            }

            messageTip.entity.SetActive(false);
            messageTip.ResetState();
            messagePool.Enqueue(messageTip);
        }
        private async void ProcessMessageQueue()
        {
            isProcessingQueue = true;

            while (messageQueue.Count > 0)
            {
                string message = messageQueue.Dequeue();
                AddNewMessage(message);

                // 等待一段时间再显示下一条消息
                await UniTask.Delay(300);
            }

            isProcessingQueue = false;
        }

        private async void AddNewMessage(string message)
        {
            MessageToast messageToast = GetMessageFromPool();

            if (messageToast != null)
            {
                messageToast.Initialize(message, messageDuration, fadeDuration);
                messageToast.OnFadeComplete += RemoveMessage;

                // 使用配置的初始位置
                RectTransform rectTransform = messageToast.rectTransform;
                rectTransform.anchoredPosition = initialPosition;

                activeMessages.Insert(0, messageToast);
                isScrolling = true;

                // 计算所有消息的目标位置
                float targetY = initialPosition.y;
                for (int i = 0; i < activeMessages.Count; i++)
                {
                    MessageToast msg = activeMessages[i];

                    if (i == 0)
                    {
                        msg.TargetPosition = new Vector2(initialPosition.x, targetY);
                        targetY += msg.rectTransform.rect.height + messageSpacing;
                    }
                    else
                    {
                        msg.TargetPosition = new Vector2(initialPosition.x, targetY);
                        targetY += msg.rectTransform.rect.height + messageSpacing;
                    }
                }

                await UniTask.WaitUntil(() => CheckScrollComplete());
                isScrolling = false;
            }
        }


        private bool CheckScrollComplete()
        {
            foreach (MessageToast message in activeMessages)
            {
                RectTransform rect = message.rectTransform;
                float distance = Vector2.Distance(rect.anchoredPosition, message.TargetPosition);
                if (distance > 0.1f)
                {
                    return false;
                }
            }
            return true;
        }

        private void RemoveMessage(MessageToast messageToast)
        {
            messageToast.OnFadeComplete -= RemoveMessage;
            activeMessages.Remove(messageToast);
            ReturnMessageToPool(messageToast);
        }
        private void ClearPool()
        {
            foreach (MessageToast message in messagePool)
            {
                GameObject.Destroy(message.entity);
            }
            messagePool.Clear();

            foreach (MessageToast message in activeMessages)
            {
                GameObject.Destroy(message.entity);
            }
            activeMessages.Clear();

            InitializePool();
        }

        private void UpdateMessagePositions()
        {
            foreach (MessageToast message in activeMessages)
            {
                RectTransform rect = message.rectTransform;
                rect.anchoredPosition = Vector2.MoveTowards(
                    rect.anchoredPosition,
                    message.TargetPosition,
                    scrollSpeed * Time.deltaTime
                );
            }
        }

        #endregion

        #region 跑马灯提示

        public void ShowMarquess(string message)
        {
            messsageMarquee.Enqueue(message);
        }

        private void PlayMarquessTween()
        {
            string message = messsageMarquee.Dequeue();
            uiToast.txt_marquee.text = message;
            int width = (int)(message.Length * uiToast.txt_marquee.fontSize);

            uiToast.marquee.SetActive(true);

            int startX = Screen.width / 2 + width / 2;
            startX += 200;

            Sequence sequence = DOTween.Sequence();
            sequence.onComplete = () => { uiToast.marquee.SetActive(messsageMarquee.Count < 1); isProcessingMarquess = false; };
            sequence.Append(uiToast.marqueeRoot.transform.DOLocalMoveX(-startX, showMarqueeTime).From(startX));
            sequence.Play();
        }

        #endregion
    }

}
